package com.commons.interceptor;

import com.alibaba.fastjson.JSON;
import com.commons.annotations.RequiredToken;
import com.commons.entity.MovieUserInfo;
import com.commons.enums.ResponseCodeEnum;
import com.commons.utils.Constance;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * @author mis_wu
 * @date 2022/3/3 10:42
 * 自定义拦截器 拦截请求 验证登录信息
 */
@Component
public class TokenInterceptor implements HandlerInterceptor {
    private static final Logger log = LoggerFactory.getLogger(TokenInterceptor.class);

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod){
            //1、获取当前请求的方法上是否存在RequiredToken注解
            boolean requiredToken = ((HandlerMethod)handler).getMethod().isAnnotationPresent(RequiredToken.class);
            //2、判断 若请求中带有token
            if (requiredToken){
                log.warn(">>> 开始token拦截器 >>>");
                //1、获取token信息
                //1-1获取请求参数中的token
//                String token=request.getParameter("token");
                //1-2获取请求头中的token
                String token=request.getHeader("token");
                if (token.startsWith("\"")){
                    token = token.substring(1,token.length());
                }
                if (token.endsWith("\"")){
                    token = token.substring(0,token.length()-1);
                }
                //2、拼接token
                String tokenKey= Constance.TOKEN_KEY+token.trim();
                log.info("tokenInterceptor当前请求的tokenkey: {}",tokenKey.toString());
                //3、根据token获取用户信息
                MovieUserInfo users=null;
                try{
                    String userStr = stringRedisTemplate.opsForValue().get(tokenKey);
                    users = JSON.parseObject(userStr,MovieUserInfo.class);
//                    users =(MovieUserInfo) redisTemplate.opsForValue().get(tokenKey);
                    log.info("login-user:{}",users);
                }catch (Exception e){
                    log.error(e.getMessage());
                    throw new NullPointerException(ResponseCodeEnum.LOGIN_INFO_ISNULL.getMsg());
                }
                //4、获取不到信息
                if (users == null || ObjectUtils.isEmpty(users)){
                    throw new RuntimeException("提示:令牌无效,token失效!");
                }else {
                    //存储到请求上下文对象中
                    request.setAttribute("token",token);
                    request.setAttribute("curruser",users);
                }
                log.warn(">>> 结束token拦截器 >>>");
            }
        }
        return true;
    }
}
